package com.iwunu.gateway.service.impl;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.iwunu.gateway.cache.RedisService;
import com.iwunu.gateway.config.MessageCofigBean;
import com.iwunu.gateway.config.MessageSplitConfigBean;
import com.iwunu.gateway.config.UrlConfig;
import com.iwunu.gateway.entity.CmdIssued;
import com.iwunu.gateway.entity.FLockLog;
import com.iwunu.gateway.entity.FaceLock;
import com.iwunu.gateway.entity.ImageMongo;
import com.iwunu.gateway.entity.OpenErrorLog;
import com.iwunu.gateway.msg.MessageConversionAdapter;
import com.iwunu.gateway.msg.MessageMapParse;
import com.iwunu.gateway.repository.CmdIssuedMongoRepository;
import com.iwunu.gateway.repository.FlockLogMongoRepository;
import com.iwunu.gateway.repository.OpenErrorLogMongoRepository;
import com.iwunu.iot.common.constant.ClientDataEnum;
import com.iwunu.iot.common.constant.ClientOpenTypeEnum;
import com.iwunu.iot.common.util.ByteTools;
import com.iwunu.iot.common.util.DateUtil;
import com.iwunu.iot.common.util.HexUtils;
import com.iwunu.iot.common.util.HttpClientUtil;
import com.iwunu.iot.common.util.StringUtil;
import com.iwunu.gateway.service.CmdIssuedMongodbService;
import com.iwunu.gateway.service.FLcokMqttReceiveService;
import com.iwunu.gateway.service.FacesLogMongodbService;
import com.iwunu.gateway.service.FlockService;
import com.iwunu.gateway.service.ImageMongodbService;
import com.iwunu.gateway.service.LockMqttServerService;

@Service
public class FlockMqttReceiveServiceImpl implements FLcokMqttReceiveService {
	private static Logger logger = LoggerFactory.getLogger(FlockMqttReceiveServiceImpl.class);
	@Autowired
	private LockMqttServerService lockMqttServerService;
	@Autowired
	private RedisService redisService;
	@Autowired
	private ImageMongodbService imageMongodbService;
	@Autowired
	private MessageConversionAdapter conversionAdapter;
	@Resource
	private MessageCofigBean messageCofigBean;
	@Autowired
	private MessageSplitConfigBean messageSplitConfigBean;
	@Autowired
	private CmdIssuedMongodbService cmdIssuedMongodbService;
	@Autowired
	private CmdIssuedMongoRepository cmdIssuedRepository;
	@Autowired
	private FlockService flockService;
	@Autowired
	private FlockLogMongoRepository flockLogMongoRepository;
	@Autowired
	private OpenErrorLogMongoRepository openErrorLogMongoRepository;
	@Autowired
	private FacesLogMongodbService facesLogMongodbService;
	@Autowired
	private HttpClintService httpClintService;
	public final static String wifiFlage = "680306";
	public final static String serviceTypeHS = "06";
	public final static String serviceTypeHC = "08";
	private final static Integer packageFm226Size = 2048;
	private final static String sendMessage = "E8";
	private final static String eventUrl = "http://nacos.hfgfgs.com:19040/weapp/uploadNbEvent";// 待修改

	/**
	 ** 人脸数据上线回复,并下发第一包数据
	 */
	@Override
	public void handlerAnswerMqttMessage(String topic, JSONObject msgjson) throws Exception {
		String msg = msgjson.getString("message");
		String deviceId = conversionAdapter.getDeviceId(msg);
//		String serviceType = messageCofigBean.getNotData();
//		try {
//			if (redisService.exitKes(deviceId + "*")) {
//				String sendData = "0000";
//				String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
//				String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
//				String sendMsg = conversionAdapter.getSendEmptyData(deviceId, sendData, serviceType, random, stamp);
//				msgjson.put("msg", sendMsg);
//				lockMqttServerService.publish(topic, msgjson.toJSONString());
//				return;
//			}
//		} catch (Exception e) {
//			logger.error("MqttCallback handlerAnswerMqttMessage:" + topic + ":" + msgjson);
//		}
		sendOpenMessage(deviceId, topic, msgjson);
		sendAddOpenTypeMessage(deviceId, topic, msgjson);
		sendDelOpenTypeMessage(deviceId, topic, msgjson);
		sendFacesImageMessage(deviceId, topic, msgjson);
		// sendFacesImageMessageOnline(deviceId, topic, msgjson);
	}

	/**
	 ** 发送人脸数据
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void sendFacesImageMessageOnline(String deviceId, String topic, JSONObject msgjson) {
		String sendMsg = "";
		String msg = msgjson.getString("message");
		try {
			String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
			String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
			ImageMongo mogoImage = imageMongodbService.getImageByDeviceId(deviceId, 9);
			JSONObject json = new JSONObject();
			json.put("flDeviceId", mogoImage.getFlDeviceId());
			json.put("clientId", mogoImage.getClientId());
			json.put("pitNum", mogoImage.getPitNum());
			json.put("size", mogoImage.getImageData().length);
			json.put("startTime", mogoImage.getStartTime());
			json.put("endTime", mogoImage.getEndTime());
			String sendData = conversionAdapter.getSendDataInfo(mogoImage.getPitNum(), mogoImage.getStartTime(),
					mogoImage.getEndTime(), mogoImage.getImageData().length);
			if (msg.startsWith(wifiFlage)) {
				sendMsg = conversionAdapter.getSendData(serviceTypeHS, deviceId, sendData.length() / 2, sendData,
						ClientDataEnum.CALLBACK.getData(), messageCofigBean.getFacesAdd(), random, stamp);
			} else {
				sendMsg = conversionAdapter.getSendData(serviceTypeHC, deviceId, sendData.length() / 2, sendData,
						ClientDataEnum.CALLBACK.getData(), messageCofigBean.getFacesAdd(), random, stamp);
			}

			redisService.set(this.getKey(deviceId, mogoImage.getPitNum(), stamp), json.toJSONString());
			msgjson.put("msg", sendMsg);
			lockMqttServerService.publish(topic, msgjson.toJSONString());
		} catch (Exception e) {
			logger.error("MqttCallback sendFacesImageMessageOnline:" + topic + ":" + msgjson);
		}

		return;
	}

	/**
	 ** 回复人脸数据
	 *
	 */
	public String handlerCallbackMqttMessage(String topic, JSONObject msgjson) {
		logger.error("MqttCallbackCallbackMqttMessage 0000000:" + topic + ":" + msgjson);
		try {
			Thread.sleep(100);
			String sendMsg = "";
			String msg = msgjson.getString("message");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String indx = conversionAdapter.getFacesIndex(msg);
			String serviceType = messageCofigBean.getCallback();
			Integer imageLength = messageSplitConfigBean.getImageLength();
			if (redisService.get(this.getRKey(deviceId, random, stamp)) == null)
				return null;
			JSONObject send = JSONObject.parseObject(redisService.get(this.getRKey(deviceId, random, stamp)));
			ImageMongo imageMongo = imageMongodbService.getImageByDeviceId(deviceId, send.getInteger("pitNum"));
			if (imageMongo != null && imageMongo.getImageData() != null) {
				byte[] sendImage = imageMongo.getImageData();
				String hexImageData = conversionAdapter.spitImageData(sendImage, Integer.parseInt(indx, 16),
						imageLength);
				if (msg.startsWith(wifiFlage)) {
					logger.error("handlerCallbackMqttMessage deviceId wifi:" + deviceId);
					sendMsg = conversionAdapter.getSendFacesData(serviceTypeHS, deviceId, imageLength, hexImageData,
							serviceType, messageCofigBean.getReviceMiniType().split(",")[8], random, stamp, indx,
							sendImage.length);
				}
				msgjson.put("msg", sendMsg);
				lockMqttServerService.publish(topic, msgjson.toJSONString());
				redisService.del(deviceId + random + stamp);
				send.put("index", Integer.parseInt(indx, 16));
				redisService.set(deviceId + random + stamp, send.toJSONString());
			} else {
				logger.error("MqttCallback handlerCallbackMqttMessage 111111111:" + topic + ":" + msgjson);
				this.handlerCallbackFm226kMqttMessage(topic, msgjson);
			}
		} catch (InterruptedException e) {
			logger.error("MqttCallback handlerCallbackMqttMessage:" + topic + ":" + msgjson);
		}

		return msgjson.toJSONString();
	}

	/**
	 ** 发送人脸数据
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void sendFacesImageMessage(String deviceId, String topic, JSONObject msgjson) {
		String sendMsg = "";
		String msg = msgjson.getString("message");
		try {
			String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
			String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
			if (redisService.listSize(deviceId + "##_" + ClientOpenTypeEnum.FM226FEATURE.getType()) != 0) {
				String serviceType = msg.startsWith(wifiFlage) ? serviceTypeHS : serviceTypeHC;
				this.sendFM226FEATUREImageMessage(deviceId, topic, msgjson, serviceType);
				return;
			} 
			if (msg.startsWith(wifiFlage)
					&& redisService.listSize(deviceId + "##_" + ClientOpenTypeEnum.FACES.getType()) != 0) {
				String sendjson = (String) redisService.leftPop(deviceId + "##_" + ClientOpenTypeEnum.FACES.getType());// 21/10/27修改内容
				JSONObject send = new JSONObject();
				send = JSONObject.parseObject(sendjson);
				send.put("count", 1);
				redisService.set(this.getRKey(deviceId, random, stamp), send.toJSONString());
				String sendData = conversionAdapter.getSendDataInfo(send.getInteger("pitNum"),
						send.getString("startTime"), send.getString("endTime"), send.getInteger("size"));
				logger.error("MqttCallback sendFacesImageMessage Image size:" + send.getInteger("size")
						+ "----Image endTime:" + send.getString("endTime") + "::"
						+ DateUtil.dateToStampS(send.getString("endTime")) / 1000 + 60 * 60 * 8 + "");

				redisService.del(deviceId + "##_" + ClientOpenTypeEnum.FEATURE.getType());
				sendMsg = conversionAdapter.getSendData(serviceTypeHS, deviceId, sendData.length() / 2, sendData,
						ClientDataEnum.CALLBACK.getData(), messageCofigBean.getFacesAdd(), random, stamp);
				msgjson.put("msg", sendMsg);
				lockMqttServerService.publish(topic, msgjson.toJSONString());
				redisService.rightPush(deviceId + "##_" + ClientOpenTypeEnum.FACES.getType(), sendjson);// 21/10/27添加内容
				return;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("MqttCallback sendFacesImageMessage:" + topic + ":" + msgjson);
		}

		return;
	}

	@Override
	public void handlerDelImageMqttMessage(String topic, JSONObject msgjson) {
		try {
			String msg = msgjson.getString("message");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String type = ClientOpenTypeEnum.DELFACES.getData();
			String serverType = ClientDataEnum.DELIMAGE.getName();
			ImageMongo imageMongo = imageMongodbService.getImageByDeviceId(deviceId, pitNum);
			if (imageMongo == null) {
				return;
			}
			logger.error("MqttCallback handlerDelImageMqttMessage:Delete" + deviceId + " : " + pitNum
					+ "---conversionAdapter.getSuccessFlag(data):" + conversionAdapter.getSuccessFlag(data));
			if (conversionAdapter.getSuccessFlag(data) == 0) {
				if (pitNum >= 50) {
					imageMongodbService.removeImageByDeviceId(deviceId);
					logger.error("MqttCallback handlerDelImageMqttMessage:Delete" + deviceId + " : " + pitNum);
				} else {
					if (imageMongo.getStatus() != null && imageMongo.getStatus() == 3
							&& imageMongo.getStatus() != 100) {
						imageMongodbService.removeImageByDeviceId(imageMongo);
					}
				}
				redisService.del(this.getRKey(deviceId, random, stamp));
				this.sendOpenMessage(deviceId, topic, msgjson);
				return;
			} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
				this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				this.sendOpenMessage(deviceId, topic, msgjson);
				return;
			} else {
				imageMongo.setSucc(false);
				imageMongodbService.updateImageStatus(imageMongo);
				redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
				redisService.del(this.getRKey(deviceId, random, stamp));
			}
			this.sendOpenMessage(deviceId, topic, msgjson);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("MqttCallback handlerDelImageMqttMessage:" + topic + ":" + msgjson);
		}
	}

	/**
	 ** 重发发送人脸数据
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void revSendFacesImageMessage(String deviceId, String topic, JSONObject msgjson, JSONObject send) {
		String sendMsg = "";
		String msg = msgjson.getString("message");
		String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
		String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
		send.put("count", 2);
		redisService.set(this.getKey(deviceId, send.getInteger("pitNum"), stamp), send.toJSONString());
		String sendData = conversionAdapter.getSendDataInfo(send.getInteger("pitNum"), send.getString("startTime"),
				send.getString("endTime"), send.getInteger("size"));
		if (msg.startsWith(wifiFlage)) {
			sendMsg = conversionAdapter.getSendData(serviceTypeHS, deviceId, sendData.length() / 2, sendData,
					ClientDataEnum.CALLBACK.getData(), messageCofigBean.getFacesAdd(), random, stamp);
		} else {
			sendMsg = conversionAdapter.getSendData(serviceTypeHC, deviceId, sendData.length() / 2, sendData,
					ClientDataEnum.CALLBACK.getData(), messageCofigBean.getFacesAdd(), random, stamp);
		}

		msgjson.put("msg", sendMsg);
		lockMqttServerService.publish(topic, msgjson.toJSONString());
	}

	/**
	 ** 人脸成功/失败处理
	 */
	@Override
	public Integer handlerSuccessMqttMessage(String topic, JSONObject msgjson) {
		try {
			String msg = msgjson.getString("message");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String serviceType = messageCofigBean.getNotData();
			if (!redisService.hasKey(this.getRKey(deviceId, random, stamp))) {
				return 0;
			}
			if (conversionAdapter.getSuccessFlag(data) == 80) {
				return 0;
			}
			JSONObject send = JSONObject.parseObject(redisService.get(this.getKey(deviceId, pitNum, stamp)));
			ImageMongo imageMongo = imageMongodbService.getImageByDeviceId(deviceId, pitNum);
			if (imageMongo == null) {
				FaceLock fl = flockService.getFaceLockByMac(deviceId);
				ImageMongo image = new ImageMongo();
				image.setEndTime(DateUtil.addYears(30));
				image.setStartTime(DateUtil.nowDateTime());
				image.setImageData(new byte[100]);
				image.setFlDeviceId(deviceId);
				image.setPitNum(pitNum);
				image.setImageUrl("");
				image.setClientId(deviceId);
				image.setUserId(fl.getOwnerId());
				image.setValid(true);
				image.setStatus(1);
				image.setRole(1);
				image.setRemark("门前录入");
				imageMongodbService.save(imageMongo);
				logger.error("MqttCallback handlerSuccessMqttMessage:" + topic + ":" + "is ok");
				return 0;
			}
			if (conversionAdapter.getSuccessFlag(data) == 0) {
				imageMongo.setSucc(true);
				imageMongo.setValid(true);
				imageMongodbService.updateImageStatus(imageMongo);
				redisService.del(this.getRKey(deviceId, random, stamp));
				Thread.sleep(100);
				redisService.rightPop(deviceId + "##_" + ClientOpenTypeEnum.FACES.getType());// 21/10/27修改内容
				this.sendFacesImageMessage(deviceId, topic, msgjson);
				return 0;
			} else if (conversionAdapter.getSuccessFlag(data) == 40) {
				imageMongodbService.removeImageByDeviceId(imageMongo);
				redisService.del(this.getRKey(deviceId, random, stamp));
				return 0;
			} else if (send.get("count") != null && send.getInteger("count") < 2) {
				if (imageMongo != null && imageMongo.isSucc() && imageMongo.isValid()) {
					return 0;
				}
				this.revSendFacesImageMessage(deviceId, topic, msgjson, send);
			} else {
				imageMongo.setSucc(false);
				imageMongo.setValid(false);
				imageMongodbService.updateImageStatus(imageMongo);
				redisService.del(this.getRKey(deviceId, random, stamp));
			}
			this.sendOpenMessage(deviceId, topic, msgjson);
			if (!redisService.exitKes(deviceId + "*")) {
				String sendData = "0000";
				random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
				stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
				String sendMsg = conversionAdapter.getSendEmptyData(deviceId, sendData, serviceType, random, stamp);
				msgjson.put("msg", sendMsg);
				lockMqttServerService.publish(topic, msgjson.toJSONString());
				return 0;
			}
		} catch (Exception e) {
			logger.error("MqttCallback handlerSuccessMqttMessage:" + topic + ":" + msgjson);
		}
		return null;

	}

	@Override
	public String handlerGeneralMqttMessage(String topic, JSONObject msgjson) {// 开锁

		try {
			FLockLog log = new FLockLog();
			String msg = msgjson.getString("message");
			logger.error("handlerGeneralMqttMessage:::::::::" + msg);
			String typeString = msgjson.getString("type").equals(ClientOpenTypeEnum.OPEN.getData()) ? "1"
					: msgjson.getString("type");
			Integer type = Integer.valueOf(typeString);
			String deviceId = conversionAdapter.getDeviceId(msg);
			String data = conversionAdapter.getData(msg);
			logger.debug("handlerGeneralMqttMessage data:" + data);
			Integer status = conversionAdapter.getSuccessFlag(data) == 0 ? 1 : 0;
			FLockLog flog = facesLogMongodbService.getFacesLog(deviceId, type);
			FaceLock fl = flockService.getFaceLockByMac(deviceId);
			if (status == 1) {
				if (type == 1) {
					redisService.del(deviceId + ClientOpenTypeEnum.OPEN.getData());
				}
				log.setSucc(true);
			} else {
				log.setSucc(false);
			}
			log.setData(status.toString());
			log.setStatus(status);
			facesLogMongodbService.save(flog);
			if (fl.getPushType() != null && fl.getPushType() == 1) {
				StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId()).append("&deviceId=")
						.append(fl.getUuid()).append("&event=").append(104).append("&electric=")
						.append(fl.getElectric()).append("&signal=").append(fl.getSignalInfo()).append("&status=")
						.append(status);
				url.append("&time=").append(DateUtil.nowDateTime());
				JSONObject result = httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				logger.error("result::" + result.toJSONString());
			}
		} catch (Exception e) {
			logger.error("MqttCallback handlerGeneralMqttMessage:" + topic + ":" + msgjson);
		}

		return msgjson.toJSONString();
	}

	/**
	 ** 获取KEY
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @return
	 */
	private String getKey(String deviceId, Integer pitNum, String stamp) {
		StringBuffer key = new StringBuffer();
		key.append(deviceId).append(pitNum).append(stamp);
		return key.toString();
	}

	/**
	 ** 获取KEY
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @return
	 */
	private String getRKey(String deviceId, String pitNum, String stamp) {
		StringBuffer key = new StringBuffer();
		key.append(deviceId).append(pitNum).append(stamp);
		return key.toString();
	}

	public void handlerPasswordMqttMessage(String topic, JSONObject msgjson) {
		String pwd = null;
		try {
			String msg = msgjson.getString("message");
			String type = msgjson.getString("type");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String serverType = ClientOpenTypeEnum.PASSWORD.getName();
			FaceLock fl = flockService.getFaceLockByMac(deviceId);
			Integer status = conversionAdapter.getSuccessFlag(data) == 0 ? 1 : 0;
			CmdIssued cmdIssued = cmdIssuedMongodbService.getCmdIssuedByDeviceId(deviceId, pitNum,
					ClientOpenTypeEnum.PASSWORD.getType());
			if (type.toUpperCase().equals(ClientOpenTypeEnum.PASSWORD.getData())) {// 待修改
				if (pitNum == 100) {
					data = conversionAdapter.getUpdatePwdData(msg);
					pwd = conversionAdapter.getUpdatePwd(data) + "";
					fl.setAdminPassword(pwd);
					flockService.update(fl);
					this.sendOpenMessage(deviceId, topic, msgjson);
					logger.error("MqttCallback handlerPasswordMqttMessage:" + topic + ":" + "is ok");
					return;
				}
				if (status == 1) {
					cmdIssued.setSucc(true);
					cmdIssued.setValid(true);
					cmdIssued.setStatus(1);
					pwd = cmdIssued.getData();
					cmdIssuedMongodbService.updateCmdIssuedStatus(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedRepository.save(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
				if (fl.getPushType() != null && fl.getPushType() == 1) {
					StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId())
							.append("&deviceId=").append(fl.getUuid()).append("&event=").append(134)
							.append("&electric=").append(fl.getElectric()).append("&signal=").append(fl.getSignalInfo())
							.append("&status=").append(status).append("&pitNum=").append(pitNum);
					if (!StringUtil.strIsNullOrEmpty(pwd)) {
						url.append("&data=").append(pwd);
					}
					url.append("&time=").append(DateUtil.nowDateTime());
					System.out.println("url::" + url.toString());
					httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				}
			} else {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					if (pitNum >= 100) {
						String openType = ClientOpenTypeEnum.DELPWD.getData();
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(deviceId, openType);
						pwd = "100";
					} else {
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					}
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
				if (fl.getPushType() != null && fl.getPushType() == 1) {
					StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId())
							.append("&deviceId=").append(fl.getUuid()).append("&event=").append(144)
							.append("&electric=").append(fl.getElectric()).append("&signal=").append(fl.getSignalInfo())
							.append("&status=").append(status).append("&pitNum=").append(pitNum);
					if (!StringUtil.strIsNullOrEmpty(pwd)) {
						url.append("&data=").append(pwd);
					}
					url.append("&time=").append(DateUtil.nowDateTime());
					System.out.println("url::" + url.toString());
					httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				}
			}
			this.sendOpenMessage(deviceId, topic, msgjson);
			this.sendAddOpenTypeMessage(deviceId, topic, msgjson);
		} catch (Exception e) {
			logger.error("MqttCallback handlerPasswordMqttMessage:" + topic + ":" + msgjson);
		}

	}

	public void handlerCardMqttMessage(String topic, JSONObject msgjson) {
		try {
			String msg = msgjson.getString("message");
			String type = msgjson.getString("type");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String serverType = ClientDataEnum.CARD.getName();
			FaceLock fl = flockService.getFaceLockByMac(deviceId);
			Integer status = conversionAdapter.getSuccessFlag(data) == 0 ? 1 : 0;
			CmdIssued cmdIssued = cmdIssuedMongodbService.getCmdIssuedByDeviceId(deviceId, pitNum,
					ClientOpenTypeEnum.CARD.getType());
			if (type.toUpperCase().equals(ClientOpenTypeEnum.CARD.getData())) {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					cmdIssued.setSucc(true);
					cmdIssued.setValid(true);
					cmdIssued.setStatus(1);
					cmdIssuedMongodbService.updateCmdIssuedStatus(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedRepository.save(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
				}
				if (fl.getPushType() != null && fl.getPushType() == 1) {
					StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId())
							.append("&deviceId=").append(fl.getUuid()).append("&event=").append(135)
							.append("&electric=").append(fl.getElectric()).append("&signal=").append(fl.getSignalInfo())
							.append("&status=").append(status).append("&pitNum=").append(pitNum);
					if (!StringUtil.strIsNullOrEmpty(cmdIssued.getData())) {
						url.append("&data=").append(cmdIssued.getData());
					}
					url.append("&time=").append(DateUtil.nowDateTime());
					httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				}
			} else {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					if (pitNum >= 100) {
						String openType = ClientOpenTypeEnum.CARD.getData();
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(deviceId, openType);
					} else {
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					}
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedMongodbService.updateCmdIssuedStatus(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
				if (fl.getPushType() != null && fl.getPushType() == 1) {
					StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId())
							.append("&deviceId=").append(fl.getUuid()).append("&event=").append(145)
							.append("&electric=").append(fl.getElectric()).append("&signal=").append(fl.getSignalInfo())
							.append("&status=").append(status).append("&pitNum=").append(pitNum);
					if (!StringUtil.strIsNullOrEmpty(cmdIssued.getData())) {
						url.append("&data=").append(cmdIssued.getData());
					}
					url.append("&time=").append(DateUtil.nowDateTime());
					httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				}
			}

		} catch (Exception e) {
			logger.error("MqttCallback handlerCardMqttMessage:" + topic + ":" + msgjson);
		}

	}

	public void handlerFingerMqttMessage(String topic, JSONObject msgjson) {
		try {
			String msg = msgjson.getString("message");
			String type = msgjson.getString("type");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String serverType = ClientDataEnum.FINGER.getName();
			CmdIssued cmdIssued = cmdIssuedMongodbService.getCmdIssuedByDeviceId(deviceId, pitNum,
					ClientOpenTypeEnum.FINGER.getType());
			if (type.toUpperCase().equals(ClientOpenTypeEnum.FINGER.getData())) {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					cmdIssued.setSucc(true);
					cmdIssued.setValid(true);
					cmdIssued.setStatus(1);
					cmdIssuedMongodbService.updateCmdIssuedStatus(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedRepository.save(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
			} else {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					if (pitNum >= 100) {
						String openType = ClientOpenTypeEnum.FINGER.getData();
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(deviceId, openType);
					} else {
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					}
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedRepository.save(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
			}
			this.sendOpenMessage(deviceId, topic, msgjson);
		} catch (Exception e) {
			logger.error("MqttCallback handlerFingerMqttMessage:" + topic + ":" + msgjson);
		}

	}

	/**
	 ** 开锁
	 * 
	 * @param deviceId
	 */
	private void sendOpenMessage(String deviceId, String topic, JSONObject msgjson) throws Exception {
		String sendData = "";
		try {
			if (redisService.hasKey(deviceId + ClientOpenTypeEnum.OPEN.getData())) {
				String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
				String stamp = HexUtils.toHexL(DateUtil.getNowTime() + 60 * 60 * 8 + "", 8);
				String status = redisService.get(deviceId + ClientOpenTypeEnum.OPEN.getData());
				String msg = msgjson.getString("message");
				String data = conversionAdapter.getOpenLockData(StringUtils.leftPad(status, 2, "0"), stamp);
				if (msg.startsWith(wifiFlage)) {
					sendData = conversionAdapter.getSendGeneralData(serviceTypeHS, deviceId, data.length() / 2, data,
							ClientDataEnum.GENERAL.getData(), ClientOpenTypeEnum.OPEN.getName(), random, stamp);
					msgjson.put("msg", sendData);
					logger.error("MqttCallback sendOpenMessage wifiFlage:" + topic + ":" + msgjson.toJSONString());
					lockMqttServerService.publish(topic, msgjson.toJSONString());
				} else {
					sendData = conversionAdapter.getSendGeneralData(serviceTypeHC, deviceId, data.length() / 2, data,
							ClientDataEnum.GENERAL.getData(), ClientOpenTypeEnum.OPEN.getName(), random, stamp);
					msgjson.put("msg", sendData);
					logger.error("MqttCallback sendOpenMessage:" + topic + ":" + msgjson.toJSONString());
					lockMqttServerService.publish(topic, msgjson.toJSONString());
				}
			}
		} catch (Exception e) {
			logger.error("MqttCallback sendOpenMessage:" + topic + ":" + msgjson);
		}

	}

	/**
	 ** 发送开门方式
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void sendAddOpenTypeMessage(String deviceId, String topic, JSONObject msgjson) throws Exception {
		String sendMsg = "";
		String sendData = "";
		String msg = msgjson.getString("message");
		Object sendPwdStr = redisService.leftPop(deviceId + "##_" + ClientOpenTypeEnum.PASSWORD.getType());
		if (sendPwdStr!=null && sendPwdStr!="") {
			try {
				String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
				String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
				JSONObject sendjson = JSONObject.parseObject(String.valueOf(sendPwdStr));
				sendMsg = sendMsg + conversionAdapter.getSendDataPwd(sendjson.getString("data"),
						sendjson.getInteger("pitNum"), ClientOpenTypeEnum.PASSWORD.getName(),
						sendjson.getString("startTime"), sendjson.getString("endTime"));
				redisService.set(this.getKey(deviceId, sendjson.getInteger("pitNum"), stamp), sendPwdStr.toString());
				if (!sendMsg.isEmpty() && msg.startsWith(wifiFlage)) {
					sendData = conversionAdapter.getSendAddOpenTypeData(serviceTypeHS, deviceId, sendMsg.length() / 2,
							sendMsg, ClientDataEnum.PASSWORD.getData(), random, stamp);
					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				} else if (!sendMsg.isEmpty() && !msg.startsWith(wifiFlage)) {
					sendData = conversionAdapter.getSendAddOpenTypeData(serviceTypeHC, deviceId, sendMsg.length() / 2,
							sendMsg, ClientDataEnum.PASSWORD.getData(), random, stamp);
					msgjson.put("msg", sendData);
					System.out.println("lockMqttServerService.publish topic：" + topic);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				}
			} catch (Exception e) {
				logger.error("MqttCallback sendAddOpenTypeMessage:" + topic + ":" + msgjson);
			}

		}
		Object sendCardNoStr = redisService.leftPop(deviceId + "##_" + ClientOpenTypeEnum.CARD.getType());
		if (sendCardNoStr!=null && sendCardNoStr!="") {
			try {
				String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
				String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
				
				JSONObject sendjson = JSONObject.parseObject(String.valueOf(sendCardNoStr));
				sendMsg = sendMsg + conversionAdapter.getSendDataCard(sendjson.getString("data"),
						sendjson.getInteger("pitNum"), ClientOpenTypeEnum.CARD.getName(),
						sendjson.getString("startTime"), sendjson.getString("endTime"));
				redisService.set(this.getKey(deviceId, sendjson.getInteger("pitNum"), stamp), sendCardNoStr.toString());
				if (!sendMsg.isEmpty() && msg.startsWith(wifiFlage)) {
					sendData = conversionAdapter.getSendAddOpenTypeData(serviceTypeHS, deviceId, sendMsg.length() / 2,
							sendMsg, ClientDataEnum.CARD.getData(), random, stamp);
					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				} else if (!sendMsg.isEmpty() && !msg.startsWith(wifiFlage)) {
					sendData = conversionAdapter.getSendAddOpenTypeData(serviceTypeHC, deviceId, sendMsg.length() / 2,
							sendMsg, ClientDataEnum.CARD.getData(), random, stamp);
					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				}
			} catch (Exception e) {
				logger.error("MqttCallback sendAddOpenTypeMessage:" + topic + ":" + msgjson);
			}
		}
		Object sendFingerStr = redisService.leftPop(deviceId + "##_" + ClientOpenTypeEnum.FINGER.getType());
		if (sendFingerStr!=null && sendFingerStr!="") {
				try {
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					JSONObject sendjson = JSONObject.parseObject(String.valueOf(sendFingerStr));
					redisService.set(this.getKey(deviceId, sendjson.getInteger("pitNum"), stamp), sendFingerStr.toString());
					sendMsg = conversionAdapter.getSendDataFinger(sendjson.getInteger("pitNum"),
							sendjson.getString("data"), sendjson.getString("startTime"), sendjson.getString("endTime"));
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendGeneralData(serviceTypeHS, deviceId, sendMsg.length() / 2,
								sendMsg, ClientDataEnum.FINGER.getData(), ClientOpenTypeEnum.FINGER.getName(), random,
								stamp);
					} else {
						sendData = conversionAdapter.getSendGeneralData(serviceTypeHC, deviceId, sendMsg.length() / 2,
								sendMsg, ClientDataEnum.FINGER.getData(), ClientOpenTypeEnum.FINGER.getName(), random,
								stamp);
					}
					msgjson.put("msg", sendData);
					lockMqttServerService.publish(topic, msgjson.toJSONString());
				} catch (Exception e) {
					logger.error("MqttCallback sendAddOpenTypeMessage:" + topic + ":" + msgjson);
				}

		}
		Object sendFeatureStr = redisService.leftPop(deviceId + "##_" + ClientOpenTypeEnum.FEATURE.getType());
		if (sendFeatureStr!=null && sendFeatureStr !=""
				&& !msg.startsWith(wifiFlage)) {
			redisService.del(deviceId + "##_" + ClientOpenTypeEnum.FACES.getType() + "");
			Thread.sleep(200);
			try {
				String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
				String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
				JSONObject json = JSONObject.parseObject(sendFeatureStr.toString());
				sendMsg = conversionAdapter.getSendDataInfo(json.getInteger("pitNum"), json.getString("feature"),
						json.getString("startTime"), json.getString("endTime"));
				sendData = conversionAdapter.getSendFacesData(deviceId, sendMsg.length() / 2, sendMsg,
						ClientDataEnum.CALLBACK.getData(), ClientOpenTypeEnum.FEATURE.getName(), random, stamp);
				msgjson.put("msg", sendData);
				logger.error("sendAddOpenTypeMessage sendData:" + sendData);
				redisService.set(this.getRKey(deviceId, random, stamp), msgjson.toJSONString());
				lockMqttServerService.publish(topic, msgjson.toJSONString());
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("MqttCallback sendAddOpenTypeMessage:" + topic + ":" + msgjson);
			}
		}
		
	}

	/**
	 ** 发送删除开门方式
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void sendDelOpenTypeMessage(String deviceId, String topic, JSONObject msgjson) {
		String sendData = "";
		String msg = msgjson.getString("message");
		try {
			Thread.sleep(100);
			Object sendPwdStr = redisService.leftPop(deviceId + ClientOpenTypeEnum.DELPWD.getData());
			if (sendPwdStr!=null && sendPwdStr!="") {
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendPwdStr.toString()),
								serviceTypeHS, ClientDataEnum.PASSWORD.getData(), ClientOpenTypeEnum.DELPWD.getName(),
								random, stamp);
					} else {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendPwdStr.toString()),
								serviceTypeHC, ClientDataEnum.PASSWORD.getData(), ClientOpenTypeEnum.DELPWD.getName(),
								random, stamp);
					}

					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
			}
			Object sendCardStr = redisService.leftPop(deviceId + ClientOpenTypeEnum.DELCARD.getData());
			if (sendCardStr!=null && sendCardStr!="") {
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendCardStr.toString()),
								serviceTypeHS, ClientDataEnum.CARD.getData(), ClientOpenTypeEnum.DELCARD.getName(),
								random, stamp);
					} else {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendCardStr.toString()),
								serviceTypeHC, ClientDataEnum.CARD.getData(), ClientOpenTypeEnum.DELCARD.getName(),
								random, stamp);
					}

					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				}
			Object sendDelfingerStr = redisService.leftPop(deviceId + ClientOpenTypeEnum.DELFINGER.getData());
			if (sendDelfingerStr!=null && sendDelfingerStr !="") {
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendDelfingerStr.toString()),
								serviceTypeHS, ClientDataEnum.FINGER.getData(), ClientOpenTypeEnum.DELFINGER.getName(),
								random, stamp);
					} else {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendDelfingerStr.toString()),
								serviceTypeHC, ClientDataEnum.FINGER.getData(), ClientOpenTypeEnum.DELFINGER.getName(),
								random, stamp);
					}
					msgjson.put("msg", sendData);
					lockMqttServerService.publish("Q.MSG.SEND.NETTY.START", msgjson.toJSONString());
				}
			Object sendDelFaceStr = redisService.leftPop(deviceId + ClientOpenTypeEnum.DELFACES.getData());
			if (sendDelFaceStr!=null && sendDelFaceStr!="") {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendDelFaceStr.toString()),
								serviceTypeHS, ClientDataEnum.DELIMAGE.getData(), ClientOpenTypeEnum.DELFACES.getName(),
								random, stamp);
					} else {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendDelFaceStr.toString()),
								serviceTypeHC, ClientDataEnum.DELIMAGE.getData(), ClientOpenTypeEnum.DELFACES.getName(),
								random, stamp);
					}
					msgjson.put("msg", sendData);
					lockMqttServerService.publish(topic, msgjson.toJSONString());
				}
			if (redisService.hasKey(deviceId + ClientOpenTypeEnum.DELADVERT.getData())) {
				while (true) {
					String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
					String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
					Object sendStr = redisService.leftPop(deviceId + ClientOpenTypeEnum.DELADVERT.getData());
					if (sendStr == null)
						break;
					if (msg.startsWith(wifiFlage)) {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendStr.toString()),
								serviceTypeHS, ClientDataEnum.OTHER.getData(), ClientOpenTypeEnum.DELADVERT.getData(),
								random, stamp);
					} else {
						sendData = conversionAdapter.getSendDelData06(deviceId, Integer.valueOf(sendStr.toString()),
								serviceTypeHC, ClientDataEnum.OTHER.getData(), ClientOpenTypeEnum.DELADVERT.getData(),
								random, stamp);
					}
					msgjson.put("msg", sendData);
					System.out.println("sendDelOpenTypeMessage DELADVERT: " + msgjson.toJSONString());
					lockMqttServerService.publish(topic, msgjson.toJSONString());
				}
			}
		} catch (Exception e) {
			logger.error("MqttCallback sendAddOpenTypeMessage:" + topic + ":" + msgjson);
		}

		return;
	}

	/**
	 * 重新发添加数据
	 * 
	 * @param deviceId
	 * @param topic
	 * @param msgjson
	 * @param pitNum
	 * @param stamp
	 * @param random
	 */
	private void revSendMessage(String deviceId, String topic, JSONObject msgjson, Integer pitNum, String stamp,
			String random, String serverType, String miniType) {
		String msg = msgjson.getString("message");
		if (msg.startsWith(wifiFlage)) {
			String sendData = conversionAdapter.getSendDelData06(deviceId, pitNum, serviceTypeHS, serverType, miniType,
					random, stamp);
			redisService.set(this.getCacheKey(deviceId, pitNum, serverType, miniType), sendData);
			msgjson.put("msg", sendData);
		}
		lockMqttServerService.publish(topic, msgjson.toJSONString());
	}

	/**
	 ** 获取缓存标记Key
	 * 
	 * @param deviceId
	 * @param pitNum
	 * @param serverType
	 * @param type
	 * @return
	 */
	private String getCacheKey(String deviceId, Integer pitNum, String serverType, String type) {
		StringBuffer sbuf = new StringBuffer();
		sbuf.append(deviceId).append("-").append(pitNum).append("-").append(serverType).append(type);
		return sbuf.toString();
	}

	@Async
	public void handlerReportMqttMessage(String topic, JSONObject msgjson) {
		try {
			String msg = conversionAdapter.getMsg(msgjson.getString("message"));
			String deviceId = conversionAdapter.getDeviceId(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getReportData(msg);
			this.changeReportMqttMessage(data, deviceId, stamp, topic, msgjson);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("MqttCallback handlerReportMqttMessage:" + topic + ":" + msgjson);
		}

	}

	public void changeReportMqttMessage(String data, String deviceId, String stamp, String topic, JSONObject msgjson) {
		try {
			String sim = "";
			String imei = "";
			String cmdData = "";
			Integer electric = 0;
			Integer signalInfo = 0;
			Integer openStatus = null;
			Integer openType = null;
			Integer event = 0;
			Integer pitNum = -1;
			Integer openTypelength = conversionAdapter.openTypeLength;
			Integer pitNumLength = conversionAdapter.pitNumLength;
			Integer multiple = conversionAdapter.multiple;
			FaceLock fl = flockService.getFaceLockByMac(deviceId);
			if (fl == null)
				return;
			if (data.length() < multiple * 3)
				return;
			Map<String, Object> datamap = MessageMapParse.parseMessage(data.length(), data);
			if (datamap.get("rep_electric") != null) {
				fl.setElectric(Integer.parseInt(datamap.get("rep_electric") + ""));
				electric = Integer.parseInt(datamap.get("rep_electric") + "");
			}
			if (datamap.get("rep_signalInfo") != null && fl.getSignalInfo() != null) {
				fl.setSignalInfo(Integer.parseInt(datamap.get("rep_signalInfo") + "") == 0 ? fl.getSignalInfo()
						: Integer.parseInt(datamap.get("rep_signalInfo") + ""));
				signalInfo = Integer.parseInt(datamap.get("rep_signalInfo") + "") == 0 ? fl.getSignalInfo()
						: Integer.parseInt(datamap.get("rep_signalInfo") + "");
			} else {
				fl.setSignalInfo(0);
			}
			if (datamap.get("rep_direction") != null) {
				openStatus = Integer.valueOf(datamap.get("rep_direction") + "") == 0 ? 1 : 0;
			}
			if (datamap.get("rep_imei") != null) {
				fl.setImei(datamap.get("rep_imei") + "");
			}
			if (datamap.get("rep_sim") != null) {
				fl.setSim(datamap.get("rep_sim") + "");
				sim = datamap.get("rep_sim").toString();
			}
			if (datamap.get("rep_openType") != null) {// MMXXSSSSSSSS开锁三元组式( MM为开锁方式
				// 02//超级密码、03//机械开锁、04//离线密码、05//离线卡、06//限时指纹、07//限时密码、08//限时感应卡、09//限时人脸))，XX为开锁坑位，SSSSSSSS为开锁信息式(密码或卡号等数据))
				String userId = null;
				Integer role = null;

				String revData = datamap.get("rep_openType") + "";
				if (revData.substring(0, openTypelength * multiple).toUpperCase().equals("FF")) {
					openType = 4;
				} else {
					openType = Integer.valueOf(revData.substring(0, openTypelength * multiple));
				}
				if (openType == 6 || openType == 7 || openType == 8 || openType == 9) {
					pitNum = Integer.valueOf(
							revData.substring((openTypelength) * multiple, (openTypelength + pitNumLength) * multiple),
							16);
				}
				if (openType == 7 || openType == 4) {
					cmdData = Integer.valueOf(
							revData.substring((openTypelength + pitNumLength) * multiple, revData.length()), 16) + "";
				} else {
					cmdData = revData.substring((openTypelength + pitNumLength) * multiple, revData.length());
				}
				if (openType == 9) {
					ImageMongo image = imageMongodbService.getImageByDeviceId(deviceId, pitNum);
					if (image != null) {
						userId = image.getUserId();
						role = image.getRole();
					} else if (topic != null) {
						String message = this.delImageData(deviceId, pitNum, msgjson);
						lockMqttServerService.publish(topic, message);
					}
				} else if (openType == 6 || openType == 7 || openType == 8 || openType == 9) {
					CmdIssued cmdIssued = cmdIssuedMongodbService.getCmdIssuedByDeviceId(deviceId, pitNum, openType);
					userId = cmdIssued.getUserId();
					role = cmdIssued.getRole();
				}
				if (openType == 2) {
					cmdData = Integer.valueOf(
							revData.substring((openTypelength + pitNumLength) * multiple, revData.length()), 16) + "";
					userId = fl.getOwnerId();
					role = 1;
				}
				FLockLog log = new FLockLog();
				log.setClientId(fl.getId().toString());
				log.setFlDeviceId(deviceId);
				log.setData(cmdData);
				log.setPitNum(pitNum);
				log.setOpenStatus(openStatus);
				log.setCreateTime(DateUtil.nowDateTime());
				log.setSerialNumber(UUID.randomUUID().toString().replace("-", ""));
				log.setSucc(true);
				log.setUserId(userId);
				log.setStatus(0);
				log.setRole(role);
				log.setType(openType);
				flockLogMongoRepository.save(log);
			}
			fl.setUpdateTime(new Date());
			if ((electric != null && electric != 0) || (signalInfo != null) || !imei.isEmpty() || !sim.isEmpty()) {
				flockService.update(fl);
			}
			if (datamap.get("rep_errorLog") != null) {
				OpenErrorLog log = new OpenErrorLog();
				String errorLogString = data.substring(0, multiple * 3);
				String errorLog = errorLogString.substring(errorLogString.length() - 2, errorLogString.length());
				logger.debug("handlerReportMqttMessage errorLog:" + errorLog);
				log.setClientId(deviceId);
				log.setCreateTime(DateUtil.nowDateTime());
				log.setFlDeviceId(deviceId);
				log.setSerialNumber(UUID.randomUUID().toString().replace("-", ""));
				log.setType(Integer.valueOf(errorLog).toString());
				openErrorLogMongoRepository.save(log);
				data = data.substring(errorLogString.length(), data.length());
			}
			if (fl.getPushType() == null || fl.getPushType() != 1)
				return;
			if (openType != null && openType != 2) {
				event = getEvent(openType);
				StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId()).append("&deviceId=")
						.append(fl.getUuid()).append("&event=").append(event).append("&electric=").append(electric)
						.append("&signal=").append(signalInfo).append("&status=").append(openStatus).append("&pitNum=")
						.append(pitNum).append("&data=");
				if (!StringUtil.strIsNullOrEmpty(cmdData)) {
					url.append(cmdData);
				}
				url.append("&time=").append(DateUtil.nowDateTime());
				JSONObject result = httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				logger.error("result+url::::" + result.toJSONString() + "::::::::url::" + url);
			}
			if (openType != null && openType == 2) {
				event = getEvent(openType);
				StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId()).append("&deviceId=")
						.append(fl.getUuid()).append("&event=").append(32).append("&electric=").append(electric)
						.append("&signal=").append(signalInfo).append("&status=").append(openStatus).append("&pitNum=")
						.append(100).append("&data=");
				if (!StringUtil.strIsNullOrEmpty(cmdData)) {
					url.append(cmdData);
				}
				url.append("&time=").append(DateUtil.nowDateTime());
				JSONObject result = httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				logger.error("result+url::::" + result.toJSONString() + "::::::::url::" + url);
			}

			if (openType == null && electric < 25) {
				StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId()).append("&deviceId=")
						.append(fl.getUuid()).append("&event=").append(110).append("&electric=").append(electric)
						.append("&signal=").append(signalInfo).append("&status=").append(1).append("&pitNum=")
						.append("").append("&data=").append("");
				url.append("&time=").append(DateUtil.nowDateTime());
				JSONObject result = httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				logger.error("result+url::::" + result.toJSONString() + "::::::::url::" + url);
			}
			if (openType == null && !sim.isEmpty()) {
				StringBuffer url = new StringBuffer(eventUrl).append("?lockId=").append(fl.getId()).append("&deviceId=")
						.append(fl.getUuid()).append("&event=").append(40).append("&electric=").append(electric)
						.append("&signal=").append(signalInfo).append("&status=").append(1).append("&pitNum=")
						.append("").append("&data=").append("").append("&sim=").append(sim);
				url.append("&time=").append(DateUtil.nowDateTime());
				JSONObject result = httpClintService.sendMessageGet(url.toString().replace(" ", "%20"));
				logger.error("result+url::::" + result.toJSONString() + "::::::::url::" + url);
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("MqttCallback handlerReportMqttMessage:" + topic + ":" + msgjson);
		}

	}

	public String delImageData(String deviceId, Integer pitNum, JSONObject msgjson) {
		String sendData = "";
		String msg = msgjson.getString("message");
		String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
		String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
		if (msg.startsWith(wifiFlage)) {
			sendData = conversionAdapter.getSendDelData06(deviceId, pitNum, serviceTypeHS,
					ClientDataEnum.DELIMAGE.getData(), ClientOpenTypeEnum.DELFACES.getName(), random, stamp);
		} else {
			sendData = conversionAdapter.getSendDelData06(deviceId, pitNum, serviceTypeHC,
					ClientDataEnum.DELIMAGE.getData(), ClientOpenTypeEnum.DELFACES.getName(), random, stamp);
		}
		msgjson.put("msg", sendData);
		return msgjson.toJSONString();
	}

	public static void main(String[] args) {

		System.out.println("68030619a7825512d8000167d3e0fc000970013a7101c17201010016".startsWith(wifiFlage));
	}

	@Override
	public void handlerOtherMqttMessage(String topic, JSONObject msgjson) throws Exception {
		try {
			String msg = msgjson.getString("message");
			String type = msgjson.getString("type");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String data = conversionAdapter.getData(msg);
			Integer pitNum = conversionAdapter.getpitNum(data);
			String serverType = ClientDataEnum.OTHER.getName();
			CmdIssued cmdIssued = cmdIssuedMongodbService.getCmdIssuedByDeviceId(deviceId, pitNum,
					ClientOpenTypeEnum.ADVERT.getType());
			if (cmdIssued == null) {
				return;
			}
			if (type.toUpperCase().equals(ClientOpenTypeEnum.ADVERT.getName())) {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					cmdIssued.setSucc(true);
					cmdIssued.setValid(true);
					cmdIssued.setStatus(1);
					cmdIssuedMongodbService.updateCmdIssuedStatus(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedRepository.save(cmdIssued);
					redisService.del(this.getKey(deviceId, pitNum, stamp));
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
				}

			}
			if (type.toUpperCase().equals(ClientOpenTypeEnum.DELADVERT.getName())) {
				if (conversionAdapter.getSuccessFlag(data) == 0) {
					if (pitNum >= 3) {
						String openType = ClientOpenTypeEnum.DELADVERT.getData();
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(deviceId, openType);
					} else {
						cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					}
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				} else if (!redisService.hasKey(this.getCacheKey(deviceId, pitNum, serverType, serverType))) {
					this.revSendMessage(deviceId, topic, msgjson, pitNum, stamp, random, serverType, type);
				} else {
					cmdIssued.setSucc(false);
					cmdIssuedMongodbService.removeCmdIssuedsByDeviceId(cmdIssued);
					redisService.del(this.getCacheKey(deviceId, pitNum, serverType, serverType));
					redisService.del(this.getKey(deviceId, pitNum, stamp));
				}
			}
			this.sendOpenMessage(deviceId, topic, msgjson);
		} catch (Exception e) {
			logger.error("MqttCallback handlerCardMqttMessage:" + topic + ":" + msgjson);
		}
	}

	/**
	 ** 发送人脸数据(第一包数据)
	 * 
	 * @param deviceId
	 * @param random
	 * @param stamp
	 * @param topic
	 * @param msgjson
	 */
	private void sendFM226FEATUREImageMessage(String deviceId, String topic, JSONObject msgjson, String serviceType) {
		try {
			String random = ByteTools.bytesToHexString(ByteTools.generateRandomBytes(2));
			String stamp = HexUtils.toHexL(DateUtil.getNowTime() + "", 8);
			if (redisService.hasKey(deviceId + ClientOpenTypeEnum.DELFACES.getData())) {
				sendDelOpenTypeMessage(deviceId, topic, msgjson);
			}

			String sendjson = (String) redisService
					.leftPop(deviceId + "##_" + ClientOpenTypeEnum.FM226FEATURE.getType());// 21/10/27修改内容
			JSONObject send = new JSONObject();
			send = JSONObject.parseObject(sendjson);
			System.out.println("sendFM226FEATUREImageMessage:::::" + send.getString("data"));
			send.put("count", 1);
			redisService.set(this.getRKey(deviceId, random, stamp), send.toJSONString());
			String sendData = conversionAdapter.getSendFm223Info(send.getInteger("pitNum"), send.getString("startTime"),
					send.getString("endTime"), send.getString("data").length(), "02");
			String sendMsg = conversionAdapter.getSendData0c(serviceType, deviceId, sendData.length() / 2, sendData,
					ClientDataEnum.CALLBACKFM226.getData(), messageCofigBean.getFm223FacesAdd(), random, stamp);
			msgjson.put("msg", sendMsg);
			System.out.println("sendFacesImageMessage:" + msgjson.toJSONString());
			lockMqttServerService.publish(topic, msgjson.toJSONString());
		} catch (Exception e) {
			logger.error("MqttCallback sendFacesImageMessage:" + topic + ":" + msgjson);
		}

		return;
	}

	/**
	 ** 回复人脸数据
	 *
	 */
	public String handlerCallbackFm226kMqttMessage(String topic, JSONObject msgjson) {

		try {
			Thread.sleep(100);
			String msg = msgjson.getString("message");
			String deviceId = conversionAdapter.getDeviceId(msg);
			String random = conversionAdapter.getRandom(msg);
			String stamp = conversionAdapter.getTimestamp(msg);
			String index = conversionAdapter.getFacesIndex(msg);
			String serviceType = messageCofigBean.getFm226Callback();
			if (redisService.get(this.getRKey(deviceId, random, stamp)) == null)
				return null;

			JSONObject send = JSONObject.parseObject(redisService.get(this.getRKey(deviceId, random, stamp)));
			if (StringUtils.isBlank(send.toJSONString())) {
				return null;
			}
			String sendImage = send.getString("data");
			String hexImageData = "";
			String sendMsg = "";
			String sendType = serviceTypeHC;
			if (msg.startsWith(wifiFlage)) {
				sendType = serviceTypeHS;
			}
			if (Integer.valueOf(index) > 0) {
				hexImageData = conversionAdapter.spitFm226ImageData(sendImage, packageFm226Size, sendImage.length());
				sendMsg = conversionAdapter.getSendFm226FacesData(deviceId, sendType, hexImageData.length(),
						hexImageData, serviceType, sendMessage, random, stamp, sendImage.length(),
						Integer.parseInt(index, 16));
			} else {
				hexImageData = conversionAdapter.spitFm226ImageData(sendImage, Integer.parseInt(index, 16),
						packageFm226Size);
				sendMsg = conversionAdapter.getSendFm226FacesData(deviceId, sendType, packageFm226Size, hexImageData,
						serviceType, sendMessage, random, stamp, sendImage.length(), 0);
			}
			msgjson.put("msg", sendMsg);

			lockMqttServerService.publish("Q.MSG.SEND.NETTY.ANSWER", msgjson.toJSONString());
			redisService.del(deviceId + random + stamp);
			send.put("index", Integer.parseInt(index, 16));
			redisService.set(deviceId + random + stamp, send.toJSONString());
		} catch (InterruptedException e) {
			logger.error("MqttCallback handlerCallbackMqttMessage:" + topic + ":" + msgjson);
		}

		return msgjson.toJSONString();
	}

	/**
	 ** 远程OTA
	 * 
	 * @param deviceId
	 */
	private void sendOTAdata(String deviceId, String topic, JSONObject msgjson) {
		try {
			if (redisService.hasKey(deviceId + ClientOpenTypeEnum.OTA.getData())) {
				String sendStr = redisService.get(deviceId + ClientOpenTypeEnum.OTA.getData());
				JSONObject sendjson = JSONObject.parseObject(String.valueOf(sendStr));
				String sendData = conversionAdapter.getOTAData(sendjson.getString("md5Str"), sendjson.getString("data"),
						sendjson.getInteger("version"), sendjson.getInteger("packSize"));
				System.out.println("sendOpenMessage:" + sendData);
				msgjson.put("msg", sendData);
				lockMqttServerService.publish(topic, msgjson.toJSONString());
			}
			return;
		} catch (Exception e) {
			logger.error("MqttCallback sendOTAdata:" + topic + ":" + msgjson);
		}

	}
	private Integer getEvent(Integer type) {
		if (type == 8 || type == 5) {
			return 10;
		} else if (type == 7 || type == 2 || type == 4) {
			return 104;
		}
		return 102;
	}
}
